package com.icarsaas.saas.component.base;

import cn.hutool.core.util.StrUtil;
import com.icarsaas.saas.common.page.FilterSoul;
import com.icarsaas.saas.common.page.Page;
import com.icarsaas.saas.common.page.SoulPage;
import com.icarsaas.saas.common.utils.Reflections;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.hibernate.Criteria;
import org.hibernate.Session;
import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Projections;
import org.hibernate.internal.CriteriaImpl;
import org.hibernate.query.NativeQuery;
import org.hibernate.query.internal.NativeQueryImpl;
import org.hibernate.transform.ResultTransformer;
import org.hibernate.transform.Transformers;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import java.io.Serializable;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

@Slf4j
public class MyBaseRepositoryImpl<T, ID extends Serializable> implements MyBaseRepository<T, ID> {
	
	/**
	 * 获取实体工厂管理对象
	 */
	@PersistenceContext(unitName = "tenantdb-persistence-unit")
	private EntityManager entityManger;
	

	/**
	 * 获取实体工厂管理对象
	 */
	public EntityManager getEntityManager() {
		return entityManger;
	}

	/**
	 * 获取 Session
	 */
	public Session getSession() {
//	  return (Session) getEntityManager().getDelegate();
//		return entityManager.unwrap(org.hibernate.Session.class);
//		return (Session) getEntityManager().getDelegate();
		return (Session) entityManger.getDelegate();
	}
	
	/**
	 * 实体类类型(由构造方法自动赋值)
	 */
	private Class<?> entityClass;
	
	/**
	 * 构造方法，根据实例类自动获取实体类类型
	 */
	public MyBaseRepositoryImpl() {
		entityClass = Reflections.getClassGenricType(getClass());
	}

	/**
	 * 强制与数据库同步
	 */
	public void flush(){
		getSession().flush();
	}

	/**
	 * 清除缓存数据
	 */
	public void clear(){ 
		getSession().clear();
	}
	
	// -------------- QL Query --------------

	/**
	 * QL 分页查询
	 * @param page
	 * @param qlString
	 * @param parameter
	 * @return
	 */
    @SuppressWarnings("unchecked")
	public <E> Page<E> find(Page<E> page, String qlString, Object... parameter){
		// get count
    	if (!page.isDisabled() && !page.isNotCount()){
	        String countQlString = "select count(*) " + removeSelect(removeOrders(qlString));  
//	        page.setCount(Long.valueOf(createQuery(countQlString, parameter).uniqueResult().toString()));
	        NativeQuery<?> query = createQuery(countQlString, parameter);
	        List<Object> list = (List<Object>) query.list();
	        if (list.size() > 0){
	        	page.setCount(Long.parseLong(list.get(0).toString()));
	        }else{
	        	page.setCount(list.size());
	        }
			if (page.getCount() < 1) {
				return page;
			}
    	}
    	// order by
    	String ql = qlString;
		if (StringUtils.isNotBlank(page.getOrderBy())){
			ql += " order by " + page.getOrderBy();
		}
		NativeQuery<?> query = createQuery(ql, parameter); 
    	// set page
        if (!page.isDisabled()){
	        query.setFirstResult(page.getFirstResult());
	        query.setMaxResults(page.getMaxResults()); 
        }
        page.setList((List<E>) query.list());
		return page;
    }
    
    /**
	 * QL 查询
	 * @param qlString
	 * @param parameter
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public <E> List<E> find(String qlString, Object... parameter){
		NativeQuery<?> query = createQuery(qlString, parameter);
		return (List<E>) query.list();
	}

	/**
	 * QL 更新
	 * @param qlString
	 * @param parameter
	 * @return
	 */
	public int update(String qlString, Object... parameter){
		return createQuery(qlString, parameter).executeUpdate();
	}
	
	/**
	 * 创建 QL 查询对象
	 * @param qlString
	 * @param parameter
	 * @return
	 */
	public NativeQuery<?> createQuery(String qlString, Object... parameter){
		NativeQuery<?> query = getSession().createSQLQuery(qlString);
		setParameter(query, parameter);
		return query;
	}
	
	// -------------- SQL Query --------------

    /**
	 * SQL 分页查询
	 * @param page
	 * @param sqlString
	 * @param parameter
	 * @return
	 */
	public <E> Page<E> findBySql(Page<E> page, String sqlString, Object... parameter){
    	return findBySql(page, sqlString, null, parameter);
    }
    
    /**
	 * SQL 分页查询
	 * @param page
	 * @param sqlString
	 * @param resultClass
	 * @param parameter
	 * @return
	 */
    @SuppressWarnings("unchecked")
	public <E> Page<E> findBySql(Page<E> page, String sqlString, Class<?> resultClass, Object... parameter){
		// get count
    	if (!page.isDisabled() && !page.isNotCount()){
	        String countSqlString = "select count(*) " + removeSelect(removeOrders(sqlString));  
//	        page.setCount(Long.valueOf(createSqlQuery(countSqlString, parameter).uniqueResult().toString()));
	        NativeQuery<?> query = createSqlQuery(countSqlString, parameter);
	        List<Object> list = (List<Object>) query.list();
	        if (list.size() > 0){
	        	page.setCount(Long.parseLong(list.get(0).toString()));
	        }else{
	        	page.setCount(list.size());
	        }
			if (page.getCount() < 1) {
				return page;
			}
    	}
    	// order by
    	String sql = sqlString;
    	String ob = page.getOrderBy();
		if (StringUtils.isNotBlank(ob)) {
			ob = ob.replace(", asc", "");
			ob = ob.replace(", desc", "");
			sql += " order by " + ob;
//			for (String order : StringUtils.split(page.getOrderBy(), ",")){
//				String[] o = StringUtils.split(order, " ");
//				if (o.length == 2) {
//					sql += " order by " + order;
//				}
//			}
			// xr 解决group查询错误的情况
			//sql += " order by " + page.getOrderBy();
		}
		NativeQuery<?> query = createSqlQuery(sql, parameter); 
		// set page
        if (!page.isDisabled()){
	        query.setFirstResult(page.getFirstResult());
	        query.setMaxResults(page.getMaxResults()); 
        }
        setResultTransformer(query, resultClass);
        page.setList((List<E>) query.list());
		return page;
    }
	
	/**
	 * SQL 查询
	 * @param sqlString
	 * @param parameter
	 * @return
	 */
	public <E> List<E> findBySql(String sqlString, Object... parameter){
		return findBySql(sqlString, null, parameter);
	}
	
	/**
	 * SQL 查询
	 * @param sqlString
	 * @param resultClass
	 * @param parameter
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public <E> List<E> findBySql(String sqlString, Class<?> resultClass, Object... parameter){
		NativeQuery<?> query = createSqlQuery(sqlString, parameter);
		setResultTransformer(query, resultClass);
		return (List<E>) query.list();
	}
	
	/**
	 * SQL 更新
	 * @param sqlString
	 * @param parameter
	 * @return
	 */
	public int updateBySql(String sqlString, Object... parameter){
		return createSqlQuery(sqlString, parameter).executeUpdate();
	}
	
	/**
	 * 创建 SQL 查询对象
	 * @param sqlString
	 * @param parameter
	 * @return
	 */
	public NativeQuery<?> createSqlQuery(String sqlString, Object... parameter){
		NativeQuery<?> query = getSession().createSQLQuery(sqlString);
		setParameter(query, parameter);
		return query;
	}
	
	// -------------- Query Tools --------------

	/**
	 * 设置查询结果类型
	 * @param query
	 * @param resultClass
	 */
	private void setResultTransformer(NativeQuery<?> query, Class<?> resultClass){
		if (resultClass != null){
			if (resultClass == Map.class){
//				query.setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP);
				query.unwrap(NativeQueryImpl.class).setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP);
			}else if (resultClass == List.class){
//				query.setResultTransformer(Transformers.TO_LIST);
				query.unwrap(NativeQueryImpl.class).setResultTransformer(Transformers.TO_LIST);
			}else{
				query.addEntity(resultClass);
			}
		}
	}
	
	/**
	 * 设置查询参数
	 * @param query
	 * @param parameter
	 */
	private void setParameter(NativeQuery<?> query, Object... parameter){
		if (parameter != null){
			for (int i=0; i<parameter.length; i++){
				query.setParameter(i, parameter[i]);
			}
		}
	}
	
    /** 
     * 去除qlString的select子句。 
     * @return
     */  
    private String removeSelect(String qlString){  
        int beginPos = qlString.toLowerCase().indexOf("from");  
        return qlString.substring(beginPos);  
    }  
      
    /** 
     * 去除hql的orderBy子句。 
     * @return
     */  
    private String removeOrders(String qlString) {  
        Pattern p = Pattern.compile("order\\s*by[\\w|\\W|\\s|\\S]*", Pattern.CASE_INSENSITIVE);  
        Matcher m = p.matcher(qlString);  
        StringBuffer sb = new StringBuffer();  
        while (m.find()) {  
            m.appendReplacement(sb, "");  
        }
        m.appendTail(sb);
        return sb.toString();  
    } 
	
	// -------------- Criteria --------------
	
	/**
	 * 分页查询
	 * @param page
	 * @return
	 */
	public Page<T> find(Page<T> page) {
		return find(page, createDetachedCriteria());
	}
	

	/**
	 * 使用检索标准对象分页查询
	 * @param page
	 * @param detachedCriteria
	 * @return
	 */
	public Page<T> find(Page<T> page, DetachedCriteria detachedCriteria) {
		return find(page, detachedCriteria, Criteria.DISTINCT_ROOT_ENTITY);
	}
	
	/**
	 * 使用检索标准对象分页查询
	 * @param page
	 * @param detachedCriteria
	 * @param resultTransformer
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public Page<T> find(Page<T> page, DetachedCriteria detachedCriteria, ResultTransformer resultTransformer) {
		// get count
		if (!page.isDisabled() && !page.isNotCount()){
			page.setCount(count(detachedCriteria));
			if (page.getCount() < 1) {
				return page;
			}
		}
		Criteria criteria = detachedCriteria.getExecutableCriteria(getSession());
		criteria.setResultTransformer(resultTransformer);
		// set page
		if (!page.isDisabled()){
	        criteria.setFirstResult(page.getFirstResult());
	        criteria.setMaxResults(page.getMaxResults()); 
		}
		// order by
		if (StringUtils.isNotBlank(page.getOrderBy())){
			for (String order : StringUtils.split(page.getOrderBy(), ",")){
				String[] o = StringUtils.split(order, " ");
				if (o.length == 2) {
					if ("DESC".equals(o[1].toUpperCase())) criteria.addOrder(Order.desc(o[0]));
					else criteria.addOrder(Order.asc(o[0]));
				}
				/* xr 当添加 jqgrid 开启 grouping 时报错
				if (o.length == 1){
					criteria.addOrder(Order.asc(o[0]));
				}else if (o.length == 2){
					if ("DESC".equals(o[1].toUpperCase())){
						criteria.addOrder(Order.desc(o[0]));
					} else {
						criteria.addOrder(Order.asc(o[0]));
					}
				}
				*/
			}
		}
		page.setList(criteria.list());
		return page;
	}

	/**
	 * 使用检索标准对象查询
	 * @param detachedCriteria
	 * @return
	 */
	public List<T> find(DetachedCriteria detachedCriteria) {
		return find(detachedCriteria, Criteria.DISTINCT_ROOT_ENTITY);
	}
	
	/**
	 * 使用检索标准对象查询
	 * @param detachedCriteria
	 * @param resultTransformer
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public List<T> find(DetachedCriteria detachedCriteria, ResultTransformer resultTransformer) {
		Criteria criteria = detachedCriteria.getExecutableCriteria(getSession());
		criteria.setResultTransformer(resultTransformer);
		return criteria.list(); 
	}
	
	/**
	 * 使用检索标准对象查询记录数
	 * @param detachedCriteria
	 * @return
	 */
	@SuppressWarnings("rawtypes")
	public long count(DetachedCriteria detachedCriteria) {
		Criteria criteria = detachedCriteria.getExecutableCriteria(getSession());
		long totalCount = 0;
		try {
			// Get orders
			Field field = CriteriaImpl.class.getDeclaredField("orderEntries");
			field.setAccessible(true);
			List orderEntrys = (List)field.get(criteria);
			// Remove orders
			field.set(criteria, new ArrayList());
			// Get count
			criteria.setProjection(Projections.rowCount());
			totalCount = Long.parseLong(criteria.uniqueResult().toString());
			// Clean count
			criteria.setProjection(null);
			// Restore orders
			field.set(criteria, orderEntrys);
		} catch (NoSuchFieldException e) {
			log.error("出错了：{}", e.getMessage());
		} catch (IllegalAccessException e) {
			log.error("出错了：{}", e.getMessage());
		}
		return totalCount;
	}

	/**
	 * 创建与会话无关的检索标准对象
	 * @param criterions Restrictions.eq("name", value);
	 * @return 
	 */
	public DetachedCriteria createDetachedCriteria(Criterion... criterions) {
		DetachedCriteria dc = DetachedCriteria.forClass(entityClass);
		for (Criterion c : criterions) {
			dc.add(c);
		}
		return dc;
	}
	
	/**
	 * 针对soul table(layer ui 表格) SQL 分页查询
	 * @param sqlString
	 * @param resultClass
	 * @param parameter
	 * @return
	 */
    @SuppressWarnings("unchecked")
	public <E> SoulPage<E> findBySqlForSoul(SoulPage<E> soulPage, String sqlString, Class<?> resultClass, Object... parameter) {
    	// order by
    	StringBuffer sql = new StringBuffer(sqlString);
    	// 获取前端指定类型  filterSos 是soultable 用于实现条件的查询
        Map<String, Map<String, String>> typeMap = soulPage.getTypeMap();
		List<FilterSoul> filterSos = soulPage.getFilterSos();
		if (filterSos != null) {
            filterSos.forEach(filterSo->{
                handleFilterSo(filterSo, typeMap, sql);
            });
        }
		// get count
    	if (!soulPage.isDisabled() && !soulPage.isNotCount()) {
	        String countSqlString = "select count(*) " + removeSelect(removeOrders(sql.toString()));  
//		        page.setCount(Long.valueOf(createSqlQuery(countSqlString, parameter).uniqueResult().toString()));
	        NativeQuery<?> query = createSqlQuery(countSqlString, parameter);
	        List<Object> list = (List<Object>) query.list();
	        if (list.size() > 0){
	        	soulPage.setCount(Long.parseLong(list.get(0).toString()));
	        }else{
	        	soulPage.setCount(list.size());
	        }
			if (soulPage.getCount() < 1) {
				return soulPage;
			}
    	}
		/*
		if (StringUtils.endsWith(filterSql, "WHERE")) {
		    filterSql.setLength(0);
		    filterSql.append("select * from (").append(sql).append(") A");
        }
        */
		/*
        // 排序
        if (StringUtils.isNotBlank(soulPage.getField())) {
            //filterSql.append(" order by ").append(fieldMap.size() > 0 ? fieldMap.get(soulPage.getField()) : soulPage.getField()).append(" ").append(soulPage.getOrder());
        }
    	*/
    	// 排序
    	String order = soulPage.getOrder();//排序方式
    	String field = soulPage.getField();//排序字段
    	if (field != null) field = StrUtil.toUnderlineCase(field);
		if (StringUtils.isNotBlank(order) && StringUtils.isNotBlank(field)) {
			order = order.replace(", asc", "");
			order = order.replace(", desc", "");
			sql.append(" order by " + field + " " + order);
		}
		NativeQuery<?> query = createSqlQuery(sql.toString(), parameter); 
		// set page
        if (!soulPage.isDisabled()){
	        query.setFirstResult(soulPage.getFirstResult());
	        query.setMaxResults(soulPage.getMaxResults()); 
        }
        setResultTransformer(query, resultClass);
        soulPage.setData((List<E>) query.list());
		return soulPage;
    }
	
    private String dbType;
	private enum DB_DIALECT {ORACLE, MYSQL};
    public String getDbType() {
		return dbType;
	}
	public void setDbType(String dbType) {
		this.dbType = dbType;
	}
    /**
     * 处理表头筛选数据
     *
     * @author Yelog
     * @date 2019-03-16 22:52
     * @param filterSo
     * @param typeMap
     * @param filterSql
     * @return void
     */
    private void handleFilterSo(FilterSoul filterSo, Map<String, Map<String, String>> typeMap, StringBuffer filterSql) {
        if (!StringUtils.endsWith(filterSql, "(") && !StringUtils.endsWith(filterSql, "WHERE")) {
            filterSql.append(StringUtils.isBlank(filterSo.getPrefix())?" and":" "+filterSo.getPrefix());
        }

        String field = filterSo.getField();
        String value = filterSo.getValue();
        switch (filterSo.getMode()) {
            case "in":
                if (filterSo.getValues()==null || filterSo.getValues().size()==0) {
                    filterSql.append(" 1=1");
                    break;
                }
                switch (typeMap.get(field)==null?"":typeMap.get(field).get("type")) {
                    case "date":
						if (DB_DIALECT.ORACLE.name().equalsIgnoreCase(dbType)) {
                            filterSql.append(" to_char(");
						} else {
                            filterSql.append(" DATE_FORMAT(");
						}

						filterSql.append(field)
                                .append(", '");
                        if (DB_DIALECT.ORACLE.name().equalsIgnoreCase(dbType)) {
                            filterSql.append(typeMap.get(field).get("value").replaceAll("HH", "HH24").replaceAll("mm", "mi"));
                        } else {
                            filterSql.append(typeMap.get(field).get("value")
                                    .replaceAll("yyyy", "%Y")
                                    .replaceAll("MM", "%m")
                                    .replaceAll("dd", "%d")
                                    .replaceAll("HH", "%H")
                                    .replaceAll("mm", "%i")
                                    .replaceAll("ss", "%s"));
                        }

                        filterSql.append("') in ('")
                                .append(StringUtils.join(filterSo.getValues(), "','"))
                                .append("')");
                        break;
                    default:
                        if (StringUtils.isBlank(filterSo.getSplit())) {
                            filterSql.append(" ")
                                    .append(field)
                                    .append(" in ('")
                                    .append(StringUtils.join(filterSo.getValues(), "','"))
                                    .append("')");
                        } else {
                            //todo 兼容value值内包含正则特殊字符
                            if (DB_DIALECT.ORACLE.name().equalsIgnoreCase(dbType)) {
                                filterSql.append(" regexp_like(")
                                        .append(field)
                                        .append(", '");
                                for (String filterSoValue : filterSo.getValues()) {
                                    filterSql.append("("+filterSo.getSplit()+"|^){1}"+filterSoValue+"("+filterSo.getSplit()+"|$){1}|");
                                }
                                filterSql.deleteCharAt(filterSql.length()-1);
                                filterSql.append("')");
                            } else {
                                filterSql.append(" ")
                                        .append(field)
                                        .append(" regexp '(");
                                for (String filterSoValue : filterSo.getValues()) {
                                    filterSql.append("("+filterSo.getSplit()+"|^){1}"+filterSoValue+"("+filterSo.getSplit()+"|$){1}|");
                                }
                                filterSql.deleteCharAt(filterSql.length()-1);
                                filterSql.append(")+'");
                            }
                        }

                        break;
                }
                break;
            case "condition":
                if (StringUtils.isBlank(filterSo.getType()) || ((!"null".equals(filterSo.getType()) && !"notNull".equals(filterSo.getType())) && StringUtils.isBlank(filterSo.getValue()))) {
                    filterSql.append(" 1=1");
                    break;
                }
                filterSql.append(" ");
                filterSql.append(field);
                switch (filterSo.getType()) {
                    case "eq":
                        filterSql.append(" = '").append(value).append("'");
                        break;
                    case "ne":
                        filterSql.append(" != '").append(value).append("'");
                        break;
                    case "gt":
                        filterSql.append(" > '").append(value).append("'");
                        break;
                    case "ge":
                        filterSql.append(" >= '").append(value).append("'");
                        break;
                    case "lt":
                        filterSql.append(" < '").append(value).append("'");
                        break;
                    case "le":
                        filterSql.append(" <= '").append(value).append("'");
                        break;
                    case "contain":
                        filterSql.append(" like '%").append(value).append("%'");
                        break;
                    case "notContain":
                        filterSql.append(" not like '%").append(value).append("%'");
                        break;
                    case "start":
                        filterSql.append(" like '").append(value).append("%'");
                        break;
                    case "end":
                        filterSql.append(" like '%").append(value).append("'");
                        break;
                    case "null":
                        filterSql.append(" is null");
                        break;
                    case "notNull":
                        filterSql.append(" is not null");
                        break;
                    default:break;
                }
                break;
            case "date":
                filterSql.append(" ");
                filterSql.append(field);
                switch (filterSo.getType()) {
                    case "yesterday":
                        if (DB_DIALECT.ORACLE.name().equalsIgnoreCase(dbType)) {
                            filterSql.append(" between trunc(sysdate - 1) and trunc(sysdate)-1/(24*60*60) ");
                        } else {
                            filterSql.append(" between date_add(curdate(), interval -1 day) and date_add(curdate(),  interval -1 second) ");
                        }
                        break;
                    case "thisWeek":
                        if (DB_DIALECT.ORACLE.name().equalsIgnoreCase(dbType)) {
                            filterSql.append(" between trunc(sysdate - to_char(sysdate-2,'D')) and trunc(sysdate - to_char(sysdate-2,'D') + 7)-1/(24*60*60) ");
                        } else {
                            filterSql.append(" between date_add(curdate(), interval - weekday(curdate()) day) and date_add(date_add(curdate(), interval - weekday(curdate())+7 day), interval -1 second) ");
                        }
                        break;
                    case "lastWeek":
                        if (DB_DIALECT.ORACLE.name().equalsIgnoreCase(dbType)) {
                            filterSql.append(" between trunc(sysdate - to_char(sysdate-2,'D') - 7) and trunc(sysdate - to_char(sysdate-2,'D'))-1/(24*60*60) ");
                        } else {
                            filterSql.append(" between date_add(curdate(), interval - weekday(curdate())-7 day) and date_add(date_add(curdate(), interval - weekday(curdate()) day), interval -1 second) ");
                        }
                        break;
                    case "thisMonth":
                        if (DB_DIALECT.ORACLE.name().equalsIgnoreCase(dbType)) {
                            filterSql.append(" between trunc(sysdate, 'mm') and trunc(last_day(sysdate)+1)-1/(24*60*60) ");
                        } else {
                            filterSql.append(" between date_add(curdate(), interval - day(curdate()) + 1 day) and DATE_ADD(last_day(curdate()), interval 24*60*60-1 second) ");
                        }
                        break;
                    case "thisYear":
                        if (DB_DIALECT.ORACLE.name().equalsIgnoreCase(dbType)) {
                            filterSql.append(" between trunc(sysdate, 'yyyy') and to_date(to_char(sysdate,'yyyy')||'-12-31 23:59:59', 'yyyy-mm-dd hh24:mi:ss') ");
                        } else {
                            filterSql.append(" between date_sub(curdate(),interval dayofyear(now())-1 day) and str_to_date(concat(year(now()),'-12-31 23:59:59'), '%Y-%m-%d %H:%i:%s') ");
                        }

                        break;
                    case "specific":
                        if (DB_DIALECT.ORACLE.name().equalsIgnoreCase(dbType)) {
                            filterSql.append(" between to_date('").append(filterSo.getValue()).append("', 'yyyy-mm-dd') and to_date('").append(filterSo.getValue()).append("', 'yyyy-mm-dd')+1-1/(24*60*60) ");
                        } else {
                            filterSql.append(" between str_to_date('").append(filterSo.getValue()).append("', '%Y-%m-%d') and str_to_date(concat('").append(filterSo.getValue()).append("',' 23:59:59'), '%Y-%m-%d %H:%i:%s') ");
                        }
                        break;
                    case "all":
                    default:
                        filterSql.delete(filterSql.lastIndexOf(" "), filterSql.length());
                        filterSql.append(" 1=1");
                        break;
                }
                break;
            case "group":
                filterSql.append(" (");
                if (filterSo.getChildren().size()>0) {
                    filterSo.getChildren().forEach(f->{
                        handleFilterSo(f, typeMap, filterSql);
                    });
                } else {
                    filterSql.append(" 1=1");
                }
                filterSql.append(" )");
            default:break;
        }

	}
    
}
